home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / Xprof / xmeasure / main.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  15KB  |  567 lines

  1. /*==================================================================
  2.  *      File :          main.c
  3.  *      Package:        Xmeasure
  4.  * 
  5.  *      Author :        Aloke Gupta.
  6.  *
  7.  *  (C) Copyright 1992, Aloke Gupta.
  8.  *  All rights granted to University of Illinois Board of Regents.
  9.  *==================================================================*/
  10. /*
  11.  * int    main(int argc, char *argv[])
  12.  * int    SetupDisplay(XD *xd)
  13.  * int    CleanupDisplay(XD *xd)
  14.  * int      ParkPointer(XD *xd);
  15.  * int    PrintServerInfo(FILE *fp, XD *xd, int argc, char **argv)
  16.  * int    Usage(char *errmsg)
  17.  * int    ListRequests()
  18.  * int    printmessage(XD *xd, char *message)
  19.  * int    Synchronize(XD *xd)
  20.  * double MeasureSyncTime(FILE *fp, XD *xd)
  21.  * int    doublecomp(i,j)
  22.  * double median(array, num)
  23.  * int    ParseCommandLine(int argc, char *argv[], XD *xd)
  24.  * int    compare(char *str1, char *str2)
  25.  */
  26.  
  27. static char copyright[] =
  28. "@(#) Copyright (c) 1992 Aloke Gupta.\n\
  29. All rights reserved.\n";
  30.  
  31. #define VERSION "1.01"
  32. char *xmeasure_version=VERSION;
  33.  
  34. #include <math.h>
  35. #include "perf.h"
  36.  
  37. extern TestRequest testrequest[];
  38.  
  39. double MeasureSyncTime();
  40.  
  41. char *prog_name;    /* Name of this program */
  42.  
  43. main(argc, argv)
  44. int argc;
  45. char *argv[];
  46. {
  47.     XD xd;        /* Some parameters of the display server */
  48.  
  49.     prog_name = argv[0];
  50.     ParseCommandLine(argc, argv, &xd);
  51.     SetupDisplay(&xd);
  52.     PrintServerInfo(stdout, &xd, argc, argv);
  53.     SetSyncTime(MeasureSyncTime(stdout, &xd));
  54.     RunTests(&xd);
  55.     printf("\n# ");
  56.     PrintTime(stdout);
  57.     CleanupDisplay(&xd);
  58.     return(0);
  59. }
  60.  
  61. /*
  62.  * Open display and set up the windows
  63.  */
  64. SetupDisplay(xd)
  65. XD   *xd;
  66. {
  67.     XSizeHints hint;
  68.     XSetWindowAttributes xswa;
  69.  
  70.     if ( (xd->display = XOpenDisplay(xd->displayname) ) == NULL) {
  71.         fprintf(stderr, "Unable to open display '%s'\n",
  72.             XDisplayName(xd->displayname));
  73.         Usage("\n");
  74.     }
  75.     xd->screen = DefaultScreen  (xd->display);
  76.     xd->cmap   = DefaultColormap(xd->display, xd->screen);
  77.     xd->visual = DefaultVisual  (xd->display, xd->screen);
  78.  
  79.     /*
  80.      * Set foreground and background attributes
  81.      */
  82.     xd->foreground = BlackPixel(xd->display, xd->screen);
  83.     xd->background = WhitePixel(xd->display, xd->screen); /* Default colors */
  84.     if (xd->fgname) {    /* A command line argument was passed */
  85.     XColor xcolor;
  86.     if (!XParseColor(xd->display, xd->cmap, xd->fgname, &xcolor)) 
  87.         fprintf(stderr, "Cannot allocate foreground color %s\n",xd->fgname);
  88.     else {
  89.         XAllocColor(xd->display, xd->cmap, &xcolor);
  90.         xd->foreground = xcolor.pixel;
  91.     }
  92.     }
  93.     if (xd->bgname) {    /* A command line argument was passed */
  94.     XColor xcolor;
  95.     if (!XParseColor(xd->display, xd->cmap, xd->bgname, &xcolor)) 
  96.         fprintf(stderr, "Cannot allocate background color %s\n",xd->bgname);
  97.     else {
  98.         XAllocColor(xd->display, xd->cmap, &xcolor);
  99.         xd->background = xcolor.pixel;
  100.     }
  101.     }
  102.  
  103.     /* 
  104.      *  Disable the screensaver and force the screen to turn on.
  105.      *  The original settings will be restored eventually.
  106.      */
  107.     XForceScreenSaver(xd->display, ScreenSaverReset);
  108.     XGetScreenSaver(xd->display, &xd->sstimeout, &xd->ssinterval,
  109.                 &xd->sspb, &xd->ssae);
  110.     XSetScreenSaver(xd->display, 32767, /* X protocol expects INT16 */
  111.             xd->ssinterval, xd->sspb, xd->ssae);
  112.  
  113.     /*
  114.      * Default positions and size of main window
  115.      */
  116.     hint.x      = XPOSITION(xd->display, xd->screen);
  117.     hint.y      = YPOSITION(xd->display, xd->screen);
  118.     hint.width  = DISPWIDTH;
  119.     hint.height = DISPHEIGHT;
  120.     hint.flags  = PPosition | PSize;
  121.     /*
  122.      * Create the main window
  123.      */
  124.     xd->window = XCreateSimpleWindow(xd->display,DefaultRootWindow(xd->display),
  125.     hint.x,hint.y,hint.width,hint.height,1,xd->foreground, xd->background);
  126.     if (xd->window == NULL) {
  127.     fprintf(stderr, "Could not create main window \n"); fflush(stderr);
  128.     exit(1);
  129.     }
  130.     xswa.override_redirect = True;
  131.     xswa.backing_store       = False;
  132.     xswa.save_under        = False;
  133.     XChangeWindowAttributes(xd->display, xd->window,
  134.             CWOverrideRedirect | CWSaveUnder | CWBackingStore, &xswa);
  135.     /*
  136.      * Create the message window
  137.      */
  138.    xd->msgwindow=XCreateSimpleWindow(xd->display,DefaultRootWindow(xd->display),
  139.         hint.x, hint.y - MSGHEIGHT - 4, hint.width, MSGHEIGHT, 1,
  140.         xd->foreground, xd->background);
  141.    if (xd->msgwindow == NULL) {
  142.     fprintf(stderr, "Could not create message window \n"); fflush(stderr);
  143.     exit(1);
  144.     }
  145.     XChangeWindowAttributes(xd->display, xd->msgwindow,
  146.         CWOverrideRedirect | CWSaveUnder | CWBackingStore, &xswa);
  147.     /* 
  148.      * Set the Graphics Contexts for the main and message windows
  149.      */
  150.     xd->gc =  XCreateGC(xd->display, xd->window, 0, 0);
  151.     XSetBackground(xd->display, xd->gc, xd->background);
  152.     XSetForeground(xd->display, xd->gc, xd->foreground);
  153.  
  154.     xd->msggc = XCreateGC(xd->display, xd->msgwindow, 0, 0);
  155.     XSetBackground(xd->display, xd->msggc, xd->background);
  156.     XSetForeground(xd->display, xd->msggc, xd->foreground);
  157.     /*
  158.      * Initialize the array of graphics contexts
  159.      */
  160.     InitGCarray(xd);
  161.     /*
  162.      * Input Event Selection
  163.      */
  164.     XSelectInput(xd->display, xd->window,
  165.     ButtonPressMask | KeyPressMask | ExposureMask);
  166.     /*
  167.      * Window Mapping
  168.      */
  169.     XMapRaised(xd->display, xd->window);
  170.     XMapRaised(xd->display, xd->msgwindow);
  171.     /*
  172.      * Move the pointer out of the way
  173.      */
  174.     ParkPointer(xd);
  175. }
  176.  
  177. CleanupDisplay(xd)
  178. XD *xd;
  179. {
  180.     int i;
  181.  
  182.     printmessage(xd, "Cleaning up display");
  183.  
  184.     XFreeGC(xd->display, xd->gc);
  185.     XFreeGC(xd->display, xd->msggc);
  186.     for (i=0; i < GFXSLOTS; i++)
  187.     XFreeGC(xd->display, xd->gcarray[i]);
  188.     XDestroyWindow(xd->display, xd->window);
  189.     XDestroyWindow(xd->display, xd->msgwindow);
  190.  
  191.     /* Restore screensaver */
  192.     XSetScreenSaver(xd->display, xd->sstimeout, xd->ssinterval,
  193.                 xd->sspb, xd->ssae);
  194. }
  195.  
  196. /*
  197.  * Move the cursor to a convenient location on the screen
  198.  */
  199. ParkPointer(xd)
  200. XD* xd;
  201. {
  202.     int xpos, ypos;
  203.     
  204.     xpos = XPOSITION(xd->display,xd->screen) + DISPWIDTH + 16;
  205.     ypos = YPOSITION(xd->display,xd->screen) + (DISPHEIGHT / 2);
  206.     XWarpPointer(xd->display, None, DefaultRootWindow(xd->display),
  207.     0, 0, 0, 0, xpos, ypos);
  208. }
  209.  
  210. /*
  211.  * Print information about the server contacted
  212.  */
  213. PrintServerInfo(fp, xd, argc, argv)
  214. FILE *fp;
  215. XD   *xd;
  216. int  argc;
  217. char *argv[];
  218. {
  219.     char hostname[128];
  220.     char *prefix = "#";    /* Turn line into a comment */
  221.     int i;
  222.  
  223.     gethostname(hostname, 128);
  224.     fprintf(fp, "%s \"%s\", version %s, running on %s.\n",
  225.         prefix, prog_name, xmeasure_version, hostname);
  226.     fprintf(fp, "%s Displaying on %s, ", prefix, DisplayString(xd->display));
  227.     i = DisplayPlanes(xd->display, xd->screen);
  228.     fprintf(fp, "which has %d color plane%c and %d color cells.\n",
  229.         i, (i == 1) ? '\0' : 's', DisplayCells(xd->display,xd->screen));
  230.     fprintf(fp, "%s %s server Version %d.%d Release %d.\n", prefix,
  231.     ServerVendor(xd->display), ProtocolVersion(xd->display),
  232.     ProtocolRevision(xd->display), VendorRelease(xd->display));
  233.  
  234.     /* 
  235.      * Now print out the command line
  236.      */
  237.     if (argc > 1) {
  238.     fprintf(fp, "%s Command line:  \"", prefix);
  239.     for (i=0; i < argc; i++)
  240.         fprintf(fp, "%s ", argv[i]);
  241.     fprintf(fp, "\"\n");
  242.     }
  243.  
  244.     /*
  245.      * Print the time
  246.      */
  247.     fprintf(fp, "%s ", prefix);
  248.     PrintTime(fp);
  249.     fflush(fp);
  250. }
  251.  
  252. Usage(errmsg)
  253. char *errmsg;
  254. {
  255.     char **ptr;
  256.     static char *options[] = {    /* Help message */
  257.     "where options include:\n",
  258.     "    -help                  Print out this help message\n",
  259.     "    -time    <s>           Run each test for <s> seconds (default = 1.0)\n",
  260.     "    -repeat  <n>           Run each test     <n> times   (default = 3)\n",
  261.     "    -<Request Name>        Run tests for this X protocol request\n",
  262.     "    -range   <Req1> <Req2> Run tests for all requests in the range specified. \n",
  263.     "    -all                   Run tests for all  X protocol requests\n",
  264.     "    -list                  List the X protocol requests\n",
  265.     "    -display <dpy>         X server on which to display\n",
  266.     "    -fg      <color>       Foreground color\n",
  267.     "    -bg      <color>       Background color\n",
  268.     "\n",
  269.     NULL
  270.     };
  271.  
  272.     fflush(stdout);
  273.     if (errmsg) fprintf(stderr, "%s: %s\n\n", prog_name, errmsg);
  274.     fprintf(stderr, "Usage: %s [-options ...]\n", prog_name);
  275.     for (ptr = options; *ptr; ptr++)
  276.     fprintf(stderr, "%s", *ptr);
  277.  
  278.     exit(1);
  279. }
  280.  
  281. ListRequests()
  282. {
  283.     int count=0, req=0;
  284.  
  285.     fprintf(stderr,"%s: The X protocol request names are:", prog_name);
  286.     for (req=0; req < MAXREQUESTS; req++) {
  287.     if (strcmp(testrequest[req].name, "Undefined Request")) {
  288.         if ((count++ % 3) == 0) 
  289.         fprintf(stderr,"\n    ");
  290.         fprintf(stderr,"%-25s", testrequest[req].name);
  291.     }
  292.     }
  293.     fprintf(stderr,"\n");
  294.     exit(1);
  295. }
  296.  
  297. /*
  298.  * Print a message in the message window
  299.  */
  300. printmessage(xd, message)
  301. XD   *xd;
  302. char *message;
  303. {
  304.     XClearWindow(xd->display, xd->msgwindow);
  305.     XDrawString (xd->display, xd->msgwindow, xd->msggc, 10,
  306.     MSGHEIGHT - (MSGHEIGHT - 10)/2, message, strlen(message) );
  307. }
  308.  
  309. /* 
  310.  * Synchronize the server and the client by checking the position of the 
  311.  * mouse on the screen.
  312.  */
  313. Synchronize(xd)
  314. XD *xd;
  315. {
  316.     Window rw,cw;
  317.     int xw, yw, xr, yr;
  318.     unsigned int keys_buttons;
  319.  
  320.     XQueryPointer(xd->display, DefaultRootWindow(xd->display), &rw, &cw,
  321.     &xw, &yw, &xr, & yr, & keys_buttons);
  322. }
  323.  
  324. /*
  325.  * Measure the synchronization time as spent in the Synchronize function
  326.  * The result is returned in seconds. The tests are run for 5000 iterations or
  327.  * 5 seconds, whichever is earlier.
  328.  */
  329. #define ITNS    5000
  330. #define MAXTIME       5.0        /* At most 5.0 seconds */
  331. #define NUMTIMES   2
  332.  
  333. double MeasureSyncTime(fp, xd)
  334. FILE *fp;
  335. XD   *xd;
  336. {
  337.     int numtimes, itns;
  338.     double itime, ftime;
  339.     double msmt[NUMTIMES];
  340.     double retval;
  341.     char message[100];
  342.  
  343.     for (numtimes = 0; numtimes < NUMTIMES; numtimes++) {
  344.     sprintf(message, "%s. Test %d of %d", 
  345.         "Measuring client-server synchronization correction",
  346.          numtimes+1, NUMTIMES); 
  347.     printmessage(xd, message);
  348.     Synchronize(xd);
  349.     /*
  350.      * Now run the measurement
  351.      */
  352.     itime = gettime();
  353.     for (itns = 0; itns < ITNS; itns++) {
  354.         Synchronize(xd);
  355.         ftime = gettime();
  356.         if ( (ftime - itime) > MAXTIME) 
  357.         break;
  358.     }
  359.     msmt[numtimes] = (ftime - itime ) / itns;
  360.     }
  361.     retval = median(msmt, NUMTIMES);
  362.     fprintf(fp,"# ");
  363.     fprintf(fp,"Synchronization correction %5.2lf ms\n", 1000.0 * retval) ;
  364.     return(retval);
  365. }
  366.  
  367. int doublecomp(i,j)
  368. double *i, *j;
  369. {
  370.     int retval=0;
  371.  
  372.     if (*i > *j)      retval  = 1;
  373.     else if (*i < *j) retval = -1;
  374.  
  375.     return(retval);
  376. }
  377.  
  378. double median(array, num)
  379. double array[];
  380. int num;
  381. {
  382.     qsort( (char *) array, num, sizeof(double), doublecomp);
  383.     if (num % 2)        /* Even number */
  384.         return((array[(num-1)/ 2] + array[num/2]) / 2);
  385.     else return(array[(num)/2]);
  386. }
  387.  
  388. ParseCommandLine(argc, argv, xd)
  389. int  argc;
  390. char *argv[];
  391. XD   *xd;
  392. {
  393.     int i, req;
  394.     Boolean success=FALSE;
  395.     char buffer[80];        /* Communicate error messages to Usage() */
  396.  
  397.     xd->displayname= NULL;    /* Initially no displayname is specified */
  398.     xd->fgname     = NULL;
  399.     xd->bgname     = NULL;
  400.  
  401.     /*
  402.      * Initially disable all requests
  403.      */
  404.     for (req=0; req < MAXREQUESTS; req++)
  405.     testrequest[req].dothis = FALSE;
  406.  
  407.     /* 
  408.      *   Now parse the command line
  409.      */
  410.     for (i=1; i < argc; i++) {
  411.     /* 
  412.      *   List legal X requests ?
  413.      */
  414.     if (!strcmp(argv[i], "-list")) 
  415.         ListRequests();
  416.     /* 
  417.      *   Print help message ?
  418.      */
  419.     if (!strcmp(argv[i], "-help")) 
  420.         Usage((char *) NULL);
  421.     /*
  422.      *   Which display to use ?
  423.      */
  424.     if (!strcmp(argv[i], "-display") || !strcmp (argv[i], "-d")) {
  425.         if (++i >= argc) 
  426.         Usage("need argument to -display");
  427.         else xd->displayname = argv[i];
  428.         continue;
  429.     }
  430.     /*
  431.      *   Set the background color
  432.      */
  433.     if (!strcmp(argv[i], "-bg")) {
  434.         if (++i >= argc) 
  435.         Usage("need background color argument to -bg");
  436.         xd->bgname = argv[i];
  437.         continue;
  438.     }
  439.     /*
  440.      *   Set the foreground color
  441.      */
  442.     if (!strcmp(argv[i], "-fg")) {
  443.         if (++i >= argc) 
  444.         Usage("need foreground color argument to -fg");
  445.         xd->fgname = argv[i];
  446.         continue;
  447.     }
  448.     /*
  449.      *   How many times to run each test ?
  450.      */
  451.     if (!strcmp(argv[i], "-repeat") ) {
  452.         int repeats;
  453.  
  454.         if (++i >= argc) 
  455.         Usage("need argument to -repeat");
  456.         else repeats = atoi(argv[i]);
  457.         if (repeats  == 0)
  458.         Usage("illegal argument to -repeat");
  459.         SetRepeats(repeats);
  460.         continue;
  461.     }
  462.     /*
  463.      *   How much time (seconds) to run each test ?
  464.      */
  465.     if (!strcmp(argv[i], "-time") ) {
  466.         float time;
  467.  
  468.         if (++i >= argc) 
  469.         Usage("need argument to -time");
  470.         else time = (float) atof(argv[i]);
  471.         if ( time == 0.0)
  472.         Usage("illegal argument to -time");
  473.         SetTesttime(time);
  474.         continue;
  475.     }
  476.     /*
  477.      *   Do them all ?
  478.      */
  479.     if (!strcmp(argv[i], "-all"))        {
  480.         for (req=0; req < MAXREQUESTS; req++)
  481.         testrequest[req].dothis = TRUE;
  482.         continue;
  483.     }
  484.     /*
  485.      *   Range of tests specified ?
  486.      */
  487.     if (!strcmp(argv[i], "-range")) {
  488.         char *name1,   *name2;
  489.         int index1 = -1, index2 = -1, tmp;
  490.  
  491.         if (++i >= argc)
  492.         Usage("need more arguments to specify -range");
  493.         else name1=argv[i];
  494.         if (++i >= argc)
  495.         Usage("need more arguments to specify -range");
  496.         else name2=argv[i];
  497.         if (*name1 == '-') name1++;
  498.         if (*name2 == '-') name2++;
  499.         /* find the indices for name1 and name2 */
  500.         for (req=0; req < MAXREQUESTS; req++)   {
  501.         if (compare(name1, testrequest[req].name) == 0)
  502.             index1 = req;
  503.         if (compare(name2, testrequest[req].name) == 0)
  504.             index2 = req;
  505.         if ((index1 != -1) && (index2!= -1))
  506.             break;
  507.         }
  508.         if (index1 == -1) {
  509.         sprintf(buffer, "unrecognized request %s", name1);
  510.         Usage(buffer);
  511.         }
  512.         if (index2 == -1) {
  513.         sprintf(buffer, "unrecognized request %s", name2);
  514.         Usage(buffer);
  515.         }
  516.         if (index1 > index2) { /* swap them if necessary */
  517.         tmp = index1; index1 = index2; index2 = tmp;
  518.         }
  519.         /* Now enable the range specified */
  520.         for (req=index1; req <= index2; req++)
  521.         testrequest[req].dothis = TRUE;
  522.  
  523.         continue;
  524.     }
  525.     /*
  526.      *   Check each legal test
  527.      */
  528.     for (req=0; req < MAXREQUESTS; req++)    {
  529.         if (compare(argv[i]+1, testrequest[req].name) == 0) {
  530.         success = testrequest[req].dothis = TRUE;
  531.         break;
  532.         }
  533.     }
  534.     if (success == TRUE) {/* Reset success, if true, and continue parsing */
  535.         success=FALSE;
  536.         continue;
  537.     }
  538.     /*
  539.      * If we have reached this far, this is a meaningless option
  540.      */
  541.     sprintf(buffer, "unrecognized option: %s", argv[i]);
  542.     Usage(buffer);
  543.     }
  544. }
  545.  
  546. /* Case insensitive comparison of two strings   */
  547. /* Returns zero if the two strings are the same */
  548.  
  549. compare(str1, str2)
  550. char *str1;
  551. char *str2;
  552. {
  553.     char c1, c2;
  554.  
  555.     while (*str1 && *str2) {
  556.      c1 = *str1++;
  557.      c2 = *str2++;
  558.      if (isupper(c1) ) c1 = tolower(c1);
  559.      if (isupper(c2) ) c2 = tolower(c2);
  560.      if (c1 != c2)
  561.          return (-1);
  562.     }
  563.     if (*str1 || *str2)
  564.      return (-1);
  565.     else return(0);
  566. }
  567.